package keqiang.com.kq_flutter_core_widget.oss;

import com.keqiang.base.GlobalParamUtils;
import com.keqiang.base.oss.OSS;
import com.zxy.tiny.Tiny;
import com.zxy.tiny.common.FileResult;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import me.zhouzhuo810.magpiex.utils.FileUtil;
import me.zhouzhuo810.magpiex.utils.StrUtil;
import me.zhouzhuo810.magpiex.utils.thread.AsyncExecutor;


/**
 * OSS多图片上传，给Flutter专用
 */
public class FlutterOssMultiPICUpload {
    /**
     * 上传图片的最大大小，单位KB
     */
    private static final int MAX_IMAGE_SIZE = 1024;
    
    private final List<Map<String, Object>> mUploadRecords;
    
    /**
     *
     */
    public FlutterOssMultiPICUpload() {
        mUploadRecords = new ArrayList<>();
    }
    
    /**
     * 图片上传
     *
     * @param keyAndPaths Flutter 传过来的数据
     *                    [{'ossKey' : '',  'filePath': '', 'uploadOk': false}]
     */
    public final List<Map<String, Object>> sync(final List<Map<String, Object>> keyAndPaths) {
        mUploadRecords.clear();
        return syncInner(keyAndPaths);
    }
    
    /**
     * 不做清除本次上传成功和失败照片集合操作
     */
    private List<Map<String, Object>> syncInner(final List<Map<String, Object>> keyAndPaths) {
        if (keyAndPaths == null || keyAndPaths.size() == 0) {
            return mUploadRecords;
        }
        
        for (Map<String, Object> map : keyAndPaths) {
            if (map == null) {
                continue;
            }
            
            String ossKey = (String) map.get("ossKey");
            String filePath = (String) map.get("filePath");
            Boolean uploadOk = map.containsKey("uploadOk") && map.get("uploadOk") != null ? (Boolean) map.get("uploadOk") : false;
            
            // 已经上传的，不上传
            if (uploadOk) {
                if (!StrUtil.isEmpty(filePath) && FileUtil.isFileExist(filePath)) {
                    File file = new File(filePath);
                    String fileName = file.getName();
                    long fileSize = file.length();
                    map.put("fileName", fileName);
                    map.put("fileSize", fileSize);
                }
                mUploadRecords.add(map);
                continue;
            }
            
            // 没有路径的，当作上传成功
            if (StrUtil.isEmpty(filePath)) {
                map.put("uploadOk", true);
                mUploadRecords.add(map);
                continue;
            }
            
            // 有路径，但是路径不存在，上传失败
            if (!StrUtil.isEmpty(filePath) && !FileUtil.isFileExist(filePath)) {
                map.put("uploadOk", false);
                mUploadRecords.add(map);
                continue;
            }
            
            File file = new File(filePath);
            String fileName = file.getName();
            long fileSize = file.length();
            
            // 压缩图片
            String compressImage = compressImage(filePath, MAX_IMAGE_SIZE);
            
            // 上传图片
            boolean upload = OSS.upload(ossKey, compressImage);
            map.put("fileName", fileName);
            map.put("fileSize", fileSize);
            map.put("uploadOk", upload);
            mUploadRecords.add(map);
            
            // 清理压缩图片
            if (!filePath.equals(compressImage)) {
                deleteScaleImg(compressImage);
            }
        }
        
        return mUploadRecords;
    }
    
    
    /**
     * 图片上传
     *
     * @param callback 上传回调
     */
    public final void async(final MultiUploadCallback callback, final List<Map<String, Object>> keyAndPaths) {
        AsyncExecutor.getInstance().execute(() -> {
            List<Map<String, Object>> result = sync(keyAndPaths);
            if (callback != null) {
                callback.callback(result);
            }
        });
    }
    
    
    /**
     * 删除上传时压缩的文件
     */
    private void deleteScaleImg(String filePath) {
        if (filePath == null) {
            return;
        }
        
        delete(filePath);
    }
    
    public interface MultiUploadCallback {
        /**
         * 不能执行UI线程操作
         */
        void callback(List<Map<String, Object>> result);
    }
    
    /**
     * @return 被删除的数据量，<=0表示删除失败
     */
    public static int delete(String filePath) {
        if (filePath == null) {
            return 0;
        }
        
        boolean ok = FileUtil.deleteFile(filePath);
        return ok ? 1 : 0;
    }
    
    private static String compressImage(String filePath, long compressLimit) {
        if (filePath == null) {
            return null;
        }
        
        File file = new File(filePath);
        if (!file.exists()) {
            return null;
        }
        Tiny.FileCompressOptions compressOptions = new Tiny.FileCompressOptions();
        compressOptions.compressDirectory = GlobalParamUtils.getScaleImgCachePath();
        compressOptions.size = compressLimit;
        
        FileResult fileResult = Tiny.getInstance().source(file).asFile()
            .withOptions(compressOptions)
            .compressSync();
        
        if (fileResult.success) {
            return fileResult.outfile;
        }
        
        return filePath;
    }
}
